Fork me on GitHub

HandlerExceptionResolver

注意:所有文章除特别说明外,转载请注明出处.

1.Spring 使用 HandlerExceptionResolver 实现全局异常捕获

首先实现的功能,我们在项目实现的过程中,项目会发生异常,但是我们并没有捕获这些异常,所以会经常出现bug等。在我们没有配置捕获全局异常时,容器会自动打印错误信息。但是如果我们在web.xml中配置,就会拦截错误,然后跳转到响应的处理错误页面。

//表示在web.xml中配置错误拦截,然后跳转到指定的错误处理界面
<error-page>
    <error-code>500</error-code>
    <location>/500.jsp</location>
</error-page>

但是现在我们在项目中通过实现Spring的HandlerExceptionResolver接口是实现所有的异常的捕获。

  • 方式一(通过实现HandlerExceptionResolver接口)使用步骤:

    1.新建GlobalExceptionResolver

    @Component
    //使用spring 利用 HandlerExceptionResolver实现全局异常捕获
    public class GlobalHandleExceptionResolver implements HandlerExceptionResolver {
        private static Logger LOG = Logger.getLogger(GlobalHandleExceptionResolver.class);
        private static  final int USER_EXCEPTION_CODE = 1;
        private static  final int OTHER_EXCEPTION_CODE =2;
    
        //编写自己需要的类
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                              Object handle, Exception ex){
            ModelAndView mv = new ModelAndView("error");
            if(ex instanceof  UserException){
                mv.addObject("message", ex.getMessage());
                mv.addObject("code",USER_EXCEPTION_CODE);
                LOG.error("用户异常:" +ex.getMessage(),ex);
            }else{
                mv.addObject("message","未知异常");
                mv.addObject("code",OTHER_EXCEPTION_CODE);
                LOG.error("未知异常:"+ ex.getMessage(),ex);
            }
            return mv;
        }
    }
    

    2.在spring配置文件中配置新建的类

    <!--全局异常捕捉 -->
    <bean class="com.ssm.exception.GlobalExceptionResolver" />
    

    3.根据需求编写自己需要处理的方法

注意:在开发的过程中如果返回null,这样的话这个类如同不起作用。如果我们想返回错误页面,那么直接在ModleAndView里面写好即可。

ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
return modelAndView;
  • 方式二(通过使用注解)使用步骤:

    1.创建GlobalExceptionResolver

    //通过使用ControllerAdvice和ExceptionHandler这两个注解实现全局的异常捕获
    @ControllerAdvice
    public class GlobalExceptionResolver {
        //这里的ServiceException是自定义的异常
        @ExceptionHandler(value = ServiceException.class)
        public @ResponseBody String serviceCommonExceptionHandler(ServiceException e) {
            //对捕获的异常进行处理并打印日志等,之后返回json数据,方式与Controller相同
            return "{'code':-1}";
        }
    
        @ExceptionHandler(value = Exception.class)
        public ModelAndView exceptionHandler() {
            //当然也可以直接返回ModelAndView等类型,然后跳转相应的错误页面,这都根据实际的需要进行使用
            return new ModelAndView();
        }
    }
    
    //自定义异常:
    public class ServiceException extends RuntimeException{
        //...
    }
    

    注意:spring会根据@ExceptionHandler的value值进行匹配,如果我们项目中的一些异常没有被捕获,那么这里就会处理一些没有捕获的异常。


2.Spring MVC 之 HandlerMethodArgumentResolver

简言之,HandlerMethodArgumentResolver = HandlerMethod + Argument(参数) + Resolver(解析器),其实就是HandlerMethod方法的解析器, 将 HttpServletRequest(header + body 中的内容)解析为HandlerMethod方法的参数。

SpringMVC中的HandlerAdapter会对Controller层方法的参数执行HandlerMethodArgumentResolver(对参数的解析器)中的方法。

HandlerMethodArgumentResolver接口主要有两个方法:supportsParameter和resolveArgument

2.1 supportsParameter()方法

boolean supportsParameter(MethodParameter parameter);

此方法返回的类型是boolean类型,作用是判断Controller层中参数是否满足条件,满足则执行resolveArgument()方法,不满足则跳过。

一般地,在supportParameter中执行getParameterAnnotations来判断是否包含这样的注解类型。getParameterAnnotations()方法表示在参数列表中经常会有添加注解的情况,所以在这种情况下使用getParameterAnnotations()方法来获得这些注解。

//在下面这个方法中有四个参数,在参数上又有注解,所以可以通过这种方法来获得
public void testa(@TestAnnocation(pat = "5") String s,@TestAnnocation2 @TestAnnocation(pat = "6") String s1,String s3,@TestAnnocation(pat = "9") String s4) {
    System.out.println("------------" + s);
}

2.2 resolveArgument()方法

此方法只会在supportsParameter()方法返回true的情况下才会调用,用于处理业务,将返回值赋值给Controller层中的参数。

Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

//判断 HandlerMethodArgumentResolver 是否支持 MethodParameter(PS: 一般都是通过 参数上面的注解|参数的类型)
public interface HandlerMethodArgumentResolver {

    //判断是否支持要转换的参数类型
    boolean supportsParameter(MethodParameter var1);

    //当支持后进行相应的转换
    //此方法中包括四个参数
    //MethodParameter parameter, M
    //odelAndViewContainer mavContainer,
    //NativeWebRequest webRequest, 
    //WebDataBinderFactory binderFactory

    Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
}

总结:我们清楚,HandlerMethodArgumentResolver是一个参数解析器,我们可以通过写一个类实现HandlerMethodArgumentResolver接口来实现对Controller层中方法参数的修改。


本文标题:HandlerExceptionResolver

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:19:19

原始链接:http://bangjinhu.github.io/undefined/自定义 HandlerExceptionResolver - 全局异常处理 HandlerMethodArgumentResolver - 入口参数解析/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.